package com.lizicloud.infrastructure.common.utils;

import java.lang.reflect.Field;
import java.io.Serializable;
import java.util.*;

/**
 * 对象操作工具类
 */
public class ObjectUtils {
    
    /**
     * 检查对象是否为空
     */
    public static boolean isNull(Object obj) {
        return obj == null;
    }
    
    /**
     * 检查对象是否不为空
     */
    public static boolean isNotNull(Object obj) {
        return obj != null;
    }
    
    /**
     * 检查对象数组是否为空
     */
    public static boolean isEmpty(Object[] array) {
        return array == null || array.length == 0;
    }
    
    /**
     * 检查对象数组是否不为空
     */
    public static boolean isNotEmpty(Object[] array) {
        return !isEmpty(array);
    }
    
    /**
     * 深拷贝对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T deepClone(T obj) {
        if (obj == null) {
            return null;
        }
        
        try {
            // 使用序列化实现深拷贝
            if (obj instanceof Serializable) {
                return (T) cloneBySerialization(obj);
            }
            
            // 对于不支持序列化的对象，使用反射拷贝
            return (T) cloneByReflection(obj);
        } catch (Exception e) {
            throw new RuntimeException("对象拷贝失败", e);
        }
    }
    
    /**
     * 通过序列化克隆对象
     */
    private static Object cloneBySerialization(Object obj) throws Exception {
        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
        java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(bos);
        oos.writeObject(obj);
        oos.flush();
        
        java.io.ByteArrayInputStream bis = new java.io.ByteArrayInputStream(bos.toByteArray());
        java.io.ObjectInputStream ois = new java.io.ObjectInputStream(bis);
        return ois.readObject();
    }
    
    /**
     * 通过反射克隆对象
     */
    private static Object cloneByReflection(Object obj) throws Exception {
        Class<?> clazz = obj.getClass();
        Object clone = clazz.newInstance();
        
        // 拷贝所有字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            Object value = field.get(obj);
            
            // 对于基本类型和不可变对象，直接赋值
            if (isImmutable(value)) {
                field.set(clone, value);
            } else if (value != null) {
                // 对于复杂对象，递归拷贝
                field.set(clone, deepClone(value));
            }
        }
        
        return clone;
    }
    
    /**
     * 检查对象是否为不可变类型
     */
    private static boolean isImmutable(Object obj) {
        if (obj == null) {
            return true;
        }
        
        Class<?> clazz = obj.getClass();
        return clazz.isPrimitive() ||
               clazz == String.class ||
               clazz == Integer.class ||
               clazz == Long.class ||
               clazz == Double.class ||
               clazz == Float.class ||
               clazz == Boolean.class ||
               clazz == Character.class ||
               clazz == Byte.class ||
               clazz == Short.class ||
               clazz.isEnum();
    }
    
    /**
     * 获取对象的字符串表示
     */
    public static String toString(Object obj) {
        if (obj == null) {
            return "null";
        }
        
        if (obj instanceof Collection) {
            return collectionToString((Collection<?>) obj);
        }
        
        if (obj instanceof Map) {
            return mapToString((Map<?, ?>) obj);
        }
        
        if (obj.getClass().isArray()) {
            return arrayToString(obj);
        }
        
        return obj.toString();
    }
    
    /**
     * 集合转字符串
     */
    private static String collectionToString(Collection<?> collection) {
        StringBuilder sb = new StringBuilder("[");
        Iterator<?> it = collection.iterator();
        while (it.hasNext()) {
            sb.append(toString(it.next()));
            if (it.hasNext()) {
                sb.append(", ");
            }
        }
        sb.append("]");
        return sb.toString();
    }
    
    /**
     * Map转字符串
     */
    private static String mapToString(Map<?, ?> map) {
        StringBuilder sb = new StringBuilder("{");
        Iterator<? extends Map.Entry<?, ?>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<?, ?> entry = it.next();
            sb.append(toString(entry.getKey())).append("=").append(toString(entry.getValue()));
            if (it.hasNext()) {
                sb.append(", ");
            }
        }
        sb.append("}");
        return sb.toString();
    }
    
    /**
     * 数组转字符串
     */
    private static String arrayToString(Object array) {
        if (array instanceof Object[]) {
            return Arrays.toString((Object[]) array);
        }
        if (array instanceof int[]) {
            return Arrays.toString((int[]) array);
        }
        if (array instanceof long[]) {
            return Arrays.toString((long[]) array);
        }
        if (array instanceof double[]) {
            return Arrays.toString((double[]) array);
        }
        if (array instanceof float[]) {
            return Arrays.toString((float[]) array);
        }
        if (array instanceof boolean[]) {
            return Arrays.toString((boolean[]) array);
        }
        if (array instanceof byte[]) {
            return Arrays.toString((byte[]) array);
        }
        if (array instanceof char[]) {
            return Arrays.toString((char[]) array);
        }
        if (array instanceof short[]) {
            return Arrays.toString((short[]) array);
        }
        return array.toString();
    }
    
    /**
     * 比较两个对象是否相等
     */
    public static boolean equals(Object obj1, Object obj2) {
        if (obj1 == obj2) {
            return true;
        }
        if (obj1 == null || obj2 == null) {
            return false;
        }
        return obj1.equals(obj2);
    }
    
    /**
     * 获取对象的哈希码
     */
    public static int hashCode(Object obj) {
        return obj == null ? 0 : obj.hashCode();
    }
    
    private ObjectUtils() {
        // 私有构造函数，防止实例化
    }
}